package busca;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;


public abstract class Busca extends Thread {
	
    protected boolean podar = true;
	private Map<Estado,Integer> fechados = null; // mapeia o estado para o seu custo g
    protected long startTime, endTime;
    protected int nosVisitados = 0;
   
	public Busca() {
    }
    protected void initFechados() {
    	fechados = new HashMap<Estado,Integer>();
    }
    public abstract No busca(Estado inicial) throws Exception;
    
    public List<No> sucessores(No pai) {
        return sucessores(pai.estado.sucessores(),pai); 
    }

    public int getNosVisitados() {
		return nosVisitados;
	}
    public boolean isPodar() {
		return podar;
	}
	public void setPodar(boolean podar) {
		this.podar = podar;
	}
    
    private List<No> sucessores(List<Estado> estados, No pai) {
        List<No> sucNo = new LinkedList<No>(); 
        for (Estado e: estados) {
            No filho = new No( e, pai);
            if (podar) {
            	 if (fechados != null) {
                     Integer custo = fechados.get(e);
                     // nao esta em fechados ou tem custo menor
                     if (custo == null || filho.g < custo.intValue()) { 
                         sucNo.add(filho);
                         fechados.put(e, filho.g);
                         nosVisitados++;
                     }
                 }
            } else {
                sucNo.add(filho);
                nosVisitados++;
            }
        }
        return sucNo;
    }
    
    public float getRunningTimeInSeconds() {
        long diff = endTime - startTime;
        if (diff < 0){ 
        	return 0.0f;
        }
        //return diff / 1000f;
        return diff;
    }

}
